package com.cloudlinkscm.base.filecenter.service.impl;

import com.cloudlinkscm.base.filecenter.common.FileCenterUtil;
import com.cloudlinkscm.base.filecenter.common.I18NUtil;
import com.cloudlinkscm.base.filecenter.domain.SysAuthCodeManager;
import com.cloudlinkscm.base.filecenter.exception.AuthenticateFailureException;
import com.cloudlinkscm.base.filecenter.exception.InvalidRequestException;
import com.cloudlinkscm.base.filecenter.model.SysAuthCode;
import com.cloudlinkscm.base.filecenter.model.dto.RequestAuthenticationDto;
import com.cloudlinkscm.base.filecenter.service.RequestAuthenticationService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @author : tac
 * @date : 2017/7/25
 */
@Service
@Profile("prod")
public class RequestAuthenticationServiceImpl implements RequestAuthenticationService {
    private SysAuthCodeManager sysAuthCodeManager;
    protected Set<String> requestHistory = new LinkedHashSet<>();       //todo:: 需要定时清理历史记录

    @Autowired
    public RequestAuthenticationServiceImpl(SysAuthCodeManager sysAuthCodeManager) {
        this.sysAuthCodeManager = sysAuthCodeManager;
    }

    @Override
    public void verifyValidity(RequestAuthenticationDto dto) throws InvalidRequestException {
        if(isRepeatRequest(dto)){
            throw new InvalidRequestException(I18NUtil.getMessage("message.prompt.authentication.repeatRequest"));
        }
        if(StringUtils.isBlank(dto.getId())){
            throw new InvalidRequestException(I18NUtil.getMessage("message.prompt.authentication.idIsBlank"));
        }
        if(StringUtils.isBlank(dto.getSysCode())){
            throw new InvalidRequestException(I18NUtil.getMessage("message.prompt.authentication.sysCodeIsBlank"));
        }
        if(isTimeout(dto)){
            throw new InvalidRequestException(I18NUtil.getMessage("message.prompt.authentication.requestExpired"));
        }
        if(StringUtils.isBlank(dto.getSign())){
            throw new InvalidRequestException(I18NUtil.getMessage("message.prompt.authentication.signIsBlank"));
        }

        requestHistory.add(dto.getId());
    }

    @Override
    public void doAuthenticate(RequestAuthenticationDto dto) throws AuthenticateFailureException {
        SysAuthCode auth = sysAuthCodeManager.getOrThrow(dto.getSysCode());
        String sign = FileCenterUtil.calculateSign(dto, auth.getAuthCode());
        if(!sign.equals(dto.getSign())){
            throw new AuthenticateFailureException(I18NUtil.getMessage("message.prompt.authentication.verifySignFailure"));
        }
    }

    protected boolean isRepeatRequest(RequestAuthenticationDto dto) {
        return requestHistory.contains(dto.getId());
    }

    protected boolean isTimeout(RequestAuthenticationDto dto) {
        //todo:: 超时时间暂时写死
        return (System.currentTimeMillis() - dto.getTimestamp()) > 10 * 1000;
    }
}
